home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 3 / Cream of the Crop 3.iso / comm / wnos5src.zip / TCPIN.C < prev    next >
Text File  |  1993-08-09  |  24KB  |  843 lines

  1. /* Process incoming TCP segments. Page number references are to ARPA RFC-793,
  2.  * the TCP specification.
  3.  */
  4. #include "global.h"
  5. #include "timer.h"
  6. #include "mbuf.h"
  7. #include "netuser.h"
  8. #include "internet.h"
  9. #include "tcp.h"
  10. #include "icmp.h"
  11. #include "iface.h"
  12. #include "ip.h"
  13.  
  14. static void near update __ARGS((struct tcb *tcb,struct tcp *seg,int16 length));
  15. static void near proc_syn __ARGS((struct tcb *tcb,char tos,struct tcp *seg));
  16. static void near add_reseq __ARGS((struct tcb *tcb,char tos,struct tcp *seg,
  17.     struct mbuf *bp,int16 length));
  18. static void near get_reseq __ARGS((struct tcb *tcb,char *tos,struct tcp *seq,
  19.     struct mbuf **bp,int16 *length));
  20. static int near trim __ARGS((struct tcb *tcb,struct tcp *seg,struct mbuf **bpp,
  21.     int16 *length));
  22. static int near in_window __ARGS((struct tcb *tcb,int32 seq));
  23.  
  24. /* This function is called from IP with the IP header in machine byte order,
  25.  * along with a mbuf chain pointing to the TCP header.
  26.  */
  27. void
  28. tcp_input(
  29. struct iface *iface,            /* Incoming interface (ignored) */
  30. struct ip *ip,                    /* IP header */
  31. struct mbuf *bp,                /* Data field, if any */
  32. int rxbroadcast)                /* Incoming broadcast - discard if true */
  33. {
  34.     struct tcb *tcb;            /* TCP Protocol control block */
  35.     struct tcp seg;                /* Local copy of segment header */
  36.     struct connection conn;        /* Local copy of addresses */
  37.     struct pseudo_header ph;    /* Pseudo-header for checksumming */
  38.     int hdrlen;                    /* Length of TCP header */
  39.     int16 length;
  40.  
  41.     if(bp == NULLBUF)
  42.         return;
  43.  
  44.     tcpInSegs++;
  45.     if(rxbroadcast)
  46.         /* Any TCP packet arriving as a broadcast is
  47.          * to be completely IGNORED!! */
  48.         goto discard;
  49.  
  50.     length = ip->length - IPLEN - ip->optlen;
  51.     ph.source = ip->source;
  52.     ph.dest = ip->dest;
  53.     ph.protocol = ip->protocol;
  54.     ph.length = length;
  55.     if(cksum(&ph,bp,length) != 0) {
  56.         /* Checksum failed, ignore segment completely */
  57.         tcpInErrs++;
  58.         goto discard;
  59.     }
  60.     /* Form local copy of TCP header in host byte order */
  61.     if((hdrlen = ntohtcp(&seg,&bp)) < 0)
  62.         /* TCP header is too small */
  63.         goto discard;
  64.  
  65.     length -= hdrlen;
  66.  
  67.     /* Fill in connection structure and find TCB */
  68.     conn.local.address = ip->dest;
  69.     conn.local.port = seg.dest;
  70.     conn.remote.address = ip->source;
  71.     conn.remote.port = seg.source;
  72.  
  73.     if((tcb = lookup_tcb(&conn)) == NULLTCB){
  74.         /* If this segment doesn't carry a SYN, reject it */
  75.         if(!seg.flags.syn)
  76.             goto discard2;
  77.  
  78.         /* See if there's a TCP_LISTEN on this socket with
  79.          * unspecified remote address and port
  80.          */
  81.         conn.remote.address = 0;
  82.         conn.remote.port = 0;
  83.  
  84.         if((tcb = lookup_tcb(&conn)) == NULLTCB) {
  85.             /* Nope, try unspecified local address too */
  86.             conn.local.address = 0;
  87.             if((tcb = lookup_tcb(&conn)) == NULLTCB)
  88.                 /* No LISTENs, so reject */
  89.                 goto discard2;
  90.         }
  91.         /* We've found an server listen socket, so clone the TCB */
  92.         if(tcb->flags.clone) {
  93.             struct tcb *ntcb = mxallocw(sizeof(struct tcb));
  94.             ASSIGN(*ntcb,*tcb);
  95.             tcb = ntcb;
  96.             tcb->timer.func = tcp_timeout;
  97.             tcb->timer.arg = tcb;
  98.             stop_timer(&tcb->timer);
  99.  
  100.             tcb->next = Tcbs;
  101.             Tcbs = tcb;
  102.         }
  103.         /* Put all the socket info into the TCB */
  104.         tcb->conn.local.address = ip->dest;
  105.         tcb->conn.remote.address = ip->source;
  106.         tcb->conn.remote.port = seg.source;
  107.     }
  108.     tcb->flags.congest = ip->flags.congest;
  109.  
  110.     /* Do unsynchronized-state processing (p. 65-68) */
  111.     switch(tcb->state){
  112.     case TCP_CLOSED:
  113.         goto discard2;
  114.     case TCP_LISTEN:
  115.         if(seg.flags.rst)
  116.             goto discard;
  117.  
  118.         if(seg.flags.ack)
  119.             goto discard2;
  120.  
  121.         if(seg.flags.syn) {
  122.             /* (Security check is bypassed) */
  123.             /* page 66 */
  124.             proc_syn(tcb,ip->tos,&seg);
  125.             send_syn(tcb);
  126.             setstate(tcb,TCP_SYN_RECEIVED);
  127.  
  128.             if(length != 0 || seg.flags.fin) {
  129.                 /* Continue processing if there's more */
  130.                 break;
  131.             }
  132.             tcp_output(tcb);
  133.         }
  134.         /* Unlikely to get here directly */
  135.         goto discard;
  136.     case TCP_SYN_SENT:
  137.         if(seg.flags.ack){
  138.             if(!seq_within(seg.ack,tcb->iss+1,tcb->snd.nxt))
  139.                 goto discard2;
  140.         }
  141.         if(seg.flags.rst){    /* p 67 */
  142.             if(seg.flags.ack){
  143.                 /* The ack must be acceptable since we just checked it.
  144.                  * This is how the remote side refuses connect requests.
  145.                  */
  146.                 close_self(tcb,RESET);
  147.             }
  148.             goto discard;
  149.         }
  150.         /* (Security check skipped here) */
  151.  
  152.         /* Check incoming precedence; it must match if there's an ACK */
  153.         if(seg.flags.ack && PREC(ip->tos) != PREC(tcb->tos))
  154.             goto discard2;
  155.  
  156.         if(seg.flags.syn){
  157.             proc_syn(tcb,ip->tos,&seg);
  158.             if(seg.flags.ack){
  159.                 /* Our SYN has been acked, otherwise the ACK
  160.                  * wouldn't have been valid.
  161.                  */
  162.                 update(tcb,&seg,length);
  163.                 setstate(tcb,TCP_ESTABLISHED);
  164.             } else {
  165.                 setstate(tcb,TCP_SYN_RECEIVED);
  166.             }
  167.             if(length != 0 || seg.flags.fin) {
  168.                 break;        /* Continue processing if there's more */
  169.             }
  170.             tcp_output(tcb);
  171.         } else {
  172.             free_p(bp);    /* Ignore if neither SYN or RST is set */
  173.         }
  174.         return;
  175.     }
  176.     /* We reach this point directly in any synchronized state. Note that
  177.      * if we fell through from LISTEN or SYN_SENT processing because of a
  178.      * data-bearing SYN, window trimming and sequence testing "cannot fail".
  179.      */
  180.  
  181.     /* Trim segment to fit receive window. */
  182.     if(trim(tcb,&seg,&bp,&length) == -1){
  183.         /* Segment is unacceptable */
  184.         if(!seg.flags.rst){    /* NEVER answer RSTs */
  185.             /* In SYN_RECEIVED state, answer a retransmitted SYN
  186.              * with a retransmitted SYN/ACK.
  187.              */
  188.             if(tcb->state == TCP_SYN_RECEIVED)
  189.                 tcb->snd.ptr = tcb->snd.una;
  190.             tcb->flags.force = 1;
  191.             tcp_output(tcb);
  192.         }
  193.         return;
  194.     }
  195.     /* If segment isn't the next one expected, and there's data
  196.      * or flags associated with it, put it on the resequencing
  197.      * queue, ACK it and return.
  198.      *
  199.      * Processing the ACK in an out-of-sequence segment without
  200.      * flags or data should be safe, however.
  201.      */
  202.     if(seg.seq != tcb->rcv.nxt
  203.      && (length != 0 || seg.flags.syn || seg.flags.fin)){
  204.         add_reseq(tcb,ip->tos,&seg,bp,length);
  205.         tcb->flags.force = 1;
  206.         tcp_output(tcb);
  207.         return;
  208.     }
  209.     /* This loop first processes the current segment, and then
  210.      * repeats if it can process the resequencing queue.
  211.      */
  212.     for(;;){
  213.         /* We reach this point with an acceptable segment; all data and flags
  214.          * are in the window, and the starting sequence number equals rcv.nxt
  215.          * (p. 70)
  216.          */
  217.         if(seg.flags.rst){
  218.             if(tcb->state == TCP_SYN_RECEIVED
  219.              && !tcb->flags.clone && !tcb->flags.active){
  220.                 /* Go back to listen state only if this was
  221.                  * not a cloned or active server TCB
  222.                  */
  223.                 setstate(tcb,TCP_LISTEN);
  224.             } else {
  225.                 close_self(tcb,RESET);
  226.             }
  227.             goto discard;
  228.         }
  229.         /* (Security check skipped here) p. 71 */
  230.         /* Check for precedence mismatch or erroneous extra SYN */
  231.         if(PREC(ip->tos) != PREC(tcb->tos) || seg.flags.syn)
  232.             goto discard2;
  233.  
  234.         /* Check ack field p. 72 */
  235.         if(!seg.flags.ack)
  236.             goto discard;    /* All segments after synchronization must have ACK */
  237.  
  238.         /* Process ACK */
  239.         switch(tcb->state){
  240.         case TCP_SYN_RECEIVED:
  241.             if(seq_within(seg.ack,tcb->snd.una+1,tcb->snd.nxt)){
  242.                 update(tcb,&seg,length);
  243.                 setstate(tcb,TCP_ESTABLISHED);
  244.             } else {
  245.                 goto discard2;
  246.             }
  247.             break;
  248.         case TCP_ESTABLISHED:
  249.         case TCP_CLOSE_WAIT:
  250.             update(tcb,&seg,length);
  251.             break;
  252.         case TCP_FINWAIT1:    /* p. 73 */
  253.             update(tcb,&seg,length);
  254.             if(tcb->sndcnt == 0){
  255.                 /* Our FIN is acknowledged */
  256.                 setstate(tcb,TCP_FINWAIT2);
  257.             }
  258.             break;
  259.         case TCP_FINWAIT2:
  260.             update(tcb,&seg,length);
  261.             break;
  262.         case TCP_CLOSING:
  263.             update(tcb,&seg,length);
  264.             if(tcb->sndcnt == 0){
  265.                 /* Our FIN is acknowledged */
  266.                 setstate(tcb,TCP_TIME_WAIT);
  267.                 set_timer(&tcb->timer,MSL2 * 1000L);
  268.                 start_timer(&tcb->timer);
  269.             }
  270.             break;
  271.         case TCP_LAST_ACK:
  272.             update(tcb,&seg,length);
  273.             if(tcb->sndcnt == 0){
  274.                 /* Our FIN is acknowledged, close connection */
  275.                 close_self(tcb,NORMAL);
  276.                 return;
  277.             }
  278.             break;
  279.         case TCP_TIME_WAIT:
  280.             start_timer(&tcb->timer);
  281.             break;
  282.         }
  283.  
  284.         /* (URGent bit processing skipped here) */
  285.  
  286.         /* Process the segment text, if any, beginning at rcv.nxt (p. 74) */
  287.         if(length != 0){
  288.             switch(tcb->state){
  289.             case TCP_SYN_RECEIVED:
  290.             case TCP_ESTABLISHED:
  291.             case TCP_FINWAIT1:
  292.             case TCP_FINWAIT2:
  293.                 /* Place on receive queue */
  294.                 append(&tcb->rcvq,bp);
  295.                 tcb->rcvcnt += length;
  296.                 tcb->rcv.nxt += length;
  297.                 tcb->rcv.wnd -= length;
  298.                 tcb->flags.force = 1;
  299.                 /* Notify user */
  300.                 if(tcb->r_upcall)
  301.                     (*tcb->r_upcall)(tcb,tcb->rcvcnt);
  302.                 break;
  303.             default:
  304.                 /* Ignore segment text */
  305.                 goto discard;
  306.             }
  307.         }
  308.         /* process FIN bit (p 75) */
  309.         if(seg.flags.fin){
  310.             tcb->flags.force = 1;    /* Always respond with an ACK */
  311.  
  312.             switch(tcb->state){
  313.             case TCP_SYN_RECEIVED:
  314.             case TCP_ESTABLISHED:
  315.                 tcb->rcv.nxt++;
  316.                 setstate(tcb,TCP_CLOSE_WAIT);
  317.                 break;
  318.             case TCP_FINWAIT1:
  319.                 tcb->rcv.nxt++;
  320.                 if(tcb->sndcnt == 0){
  321.                     /* Our FIN has been acked; bypass TCP_CLOSING state */
  322.                     setstate(tcb,TCP_TIME_WAIT);
  323.                     set_timer(&tcb->timer,MSL2 * 1000L);
  324.                     start_timer(&tcb->timer);
  325.                 } else {
  326.                     setstate(tcb,TCP_CLOSING);
  327.                 }
  328.                 break;
  329.             case TCP_FINWAIT2:
  330.                 tcb->rcv.nxt++;
  331.                 setstate(tcb,TCP_TIME_WAIT);
  332.                 set_timer(&tcb->timer,MSL2 * 1000L);
  333.                 start_timer(&tcb->timer);
  334.                 break;
  335.             case TCP_CLOSE_WAIT:
  336.             case TCP_CLOSING:
  337.             case TCP_LAST_ACK:
  338.                 break;        /* Ignore */
  339.             case TCP_TIME_WAIT:    /* p 76 */
  340.                 start_timer(&tcb->timer);
  341.                 break;
  342.             }
  343.             /* Call the client again so he can see EOF */
  344.             if(tcb->r_upcall)
  345.                 (*tcb->r_upcall)(tcb,tcb->rcvcnt);
  346.         }
  347.         /* Scan the resequencing queue, looking for a segment we can handle,
  348.          * and freeing all those that are now obsolete.
  349.          */
  350.         while(tcb->reseq != NULLRESEQ && seq_ge(tcb->rcv.nxt,tcb->reseq->seg.seq)){
  351.             get_reseq(tcb,&ip->tos,&seg,&bp,&length);
  352.             if(trim(tcb,&seg,&bp,&length) == 0)
  353.                 goto gotone;
  354.             /* Segment is an old one; trim has freed it */
  355.         }
  356.         break;
  357. gotone:    ;
  358.     }
  359.     tcp_output(tcb);    /* Send any necessary ack */
  360.     return;
  361. discard:
  362.     free_p(bp);
  363.     return;
  364. discard2:
  365.     free_p(bp);
  366.     reset(ip,&seg);
  367.     return;
  368. }
  369.  
  370. /* Process an incoming ICMP response */
  371. void
  372. tcp_icmp(
  373. int32 icsource,            /* Sender of ICMP message (not used) */
  374. int32 source,            /* Original IP datagram source (i.e. us) */
  375. int32 dest,                /* Original IP datagram dest (i.e., them) */
  376. char type,
  377. char code,                /* ICMP error codes */
  378. struct mbuf **bpp)        /* First 8 bytes of TCP header */
  379. {
  380.     struct tcp seg;
  381.     struct connection conn;
  382.     struct tcb *tcb;
  383.  
  384.     /* Extract the socket info from the returned TCP header fragment
  385.      * Note that since this is a datagram we sent, the source fields
  386.      * refer to the local side.
  387.      */
  388.     ntohtcp(&seg,bpp);
  389.     conn.local.port = seg.source;
  390.     conn.remote.port = seg.dest;
  391.     conn.local.address = source;
  392.     conn.remote.address = dest;
  393.     if((tcb = lookup_tcb(&conn)) == NULLTCB)
  394.         return;    /* Unknown connection, ignore */
  395.  
  396.     /* Verify that the sequence number in the returned segment corresponds
  397.      * to something currently unacknowledged. If not, it can safely
  398.      * be ignored.
  399.      */
  400.     if(!seq_within(seg.seq,tcb->snd.una,tcb->snd.nxt))
  401.         return;
  402.  
  403.     /* Destination Unreachable and Time Exceeded messages never kill a
  404.      * connection; the info is merely saved for future reference.
  405.      */
  406.     switch(uchar(type)){
  407.     case ICMP_DEST_UNREACH:
  408.     case ICMP_TIME_EXCEED:
  409.         tcb->type = type;
  410.         tcb->code = code;
  411.         break;
  412.     case ICMP_QUENCH:
  413.         /* Source quench; cut the congestion window in half,
  414.          * but don't let it go below one packet
  415.          */
  416.         tcb->cwind /= 2;
  417.         tcb->cwind = max(tcb->mss,tcb->cwind);
  418.         break;
  419.     }
  420. }
  421.  
  422. /* Send an acceptable reset (RST) response for this segment
  423.  * The RST reply is composed in place on the input segment
  424.  */
  425. void
  426. reset(
  427. struct ip *ip,            /* Offending IP header */
  428. struct tcp *seg)        /* Offending TCP header */
  429. {
  430.     struct mbuf *hbp;
  431.     struct pseudo_header ph;
  432.     int16 tmp;
  433.  
  434.     if(seg->flags.rst)
  435.         return;    /* Never send an RST in response to an RST */
  436.  
  437.     /* Compose the RST IP pseudo-header, swapping addresses */
  438.     ph.source = ip->dest;
  439.     ph.dest = ip->source;
  440.     ph.protocol = TCP_PTCL;
  441.     ph.length = TCPLEN;
  442.  
  443.     /* Swap port numbers */
  444.     tmp = seg->source;
  445.     seg->source = seg->dest;
  446.     seg->dest = tmp;
  447.  
  448.     if(seg->flags.ack){
  449.         /* This reset is being sent to clear a half-open connection.
  450.          * Set the sequence number of the RST to the incoming ACK
  451.          * so it will be acceptable.
  452.          */
  453.         seg->flags.ack = 0;
  454.         seg->seq = seg->ack;
  455.         seg->ack = 0;
  456.     } else {
  457.         /* We're rejecting a connect request (SYN) from TCP_LISTEN state
  458.          * so we have to "acknowledge" their SYN.
  459.          */
  460.         seg->flags.ack = 1;
  461.         seg->ack = seg->seq;
  462.         seg->seq = 0;
  463.         if(seg->flags.syn)
  464.             seg->ack++;
  465.     }
  466.     /* Set remaining parts of packet */
  467.     seg->flags.urg = 0;
  468.     seg->flags.psh = 0;
  469.     seg->flags.rst = 1;
  470.     seg->flags.syn = 0;
  471.     seg->flags.fin = 0;
  472.     seg->wnd = 0;
  473.     seg->up = 0;
  474.     seg->mss = 0;
  475.     seg->optlen = 0;
  476.     hbp = htontcp(seg,NULLBUF,&ph);
  477.  
  478.     /* Ship it out (note swap of addresses) */
  479.     ip_send(ip->dest,ip->source,TCP_PTCL,ip->tos,0,hbp,ph.length,0,0);
  480.     tcpOutRsts++;
  481. }
  482.  
  483. /* Process an incoming acknowledgement and window indication.
  484.  * From page 72.
  485.  */
  486. static void near
  487. update(struct tcb *tcb,struct tcp *seg,int16 length)
  488. {
  489.     int16 acked = 0, expand;
  490.  
  491.     if(seq_gt(seg->ack,tcb->snd.nxt)){
  492.         tcb->flags.force = 1;    /* Acks something not yet sent */
  493.         return;
  494.     }
  495.     /* Decide if we need to do a window update.
  496.      * This is always checked whenever a legal ACK is received,
  497.      * even if it doesn't actually acknowledge anything,
  498.      * because it might be a spontaneous window reopening.
  499.      */
  500.     if(seq_gt(seg->seq,tcb->snd.wl1) || ((seg->seq == tcb->snd.wl1)
  501.      && seq_ge(seg->ack,tcb->snd.wl2))){
  502.         /* If the window had been closed, crank back the
  503.          * send pointer so we'll immediately resume transmission.
  504.          * Otherwise we'd have to wait until the next probe.
  505.          */
  506.         if(tcb->snd.wnd == 0 && seg->wnd != 0)
  507.             tcb->snd.ptr = tcb->snd.una;
  508.         tcb->snd.wnd = seg->wnd;
  509.         tcb->snd.wl1 = seg->seq;
  510.         tcb->snd.wl2 = seg->ack;
  511.     }
  512.     /* See if anything new is being acknowledged */
  513.     if(!seq_gt(seg->ack,tcb->snd.una)){
  514.         if(seg->ack != tcb->snd.una)
  515.             return;    /* Old ack, ignore */
  516.  
  517.         if(length != 0 || seg->flags.syn || seg->flags.fin)
  518.             return;    /* Nothing acked, but there is data */
  519.  
  520.         /* Van Jacobson "fast recovery" code */
  521.         if(++tcb->dupacks == TCPDUPACKS){
  522.             /* We've had a burst of do-nothing acks, so
  523.              * we almost certainly lost a packet.
  524.              * Resend it now to avoid a timeout. (This is
  525.              * Van Jacobson's 'quick recovery' algorithm.)
  526.              */
  527.             int32 ptrsave;
  528.  
  529.             /* Knock the threshold down just as though
  530.              * this were a timeout, since we've had
  531.              * network congestion.
  532.              */
  533.             tcb->ssthresh = tcb->cwind/2;
  534.             tcb->ssthresh = max(tcb->ssthresh,tcb->mss);
  535.  
  536.             /* Manipulate the machinery in tcp_output() to
  537.              * retransmit just the missing packet
  538.              */
  539.             ptrsave = tcb->snd.ptr;
  540.             tcb->snd.ptr = tcb->snd.una;
  541.             tcb->cwind = tcb->mss;
  542.             tcp_output(tcb);
  543.             tcb->snd.ptr = ptrsave;
  544.  
  545.             /* "Inflate" the congestion window, pretending as
  546.              * though the duplicate acks were normally acking
  547.              * the packets beyond the one that was lost.
  548.              */
  549.             tcb->cwind = tcb->ssthresh + TCPDUPACKS * tcb->mss;
  550.         } else if(tcb->dupacks > TCPDUPACKS){
  551.             /* Continue to inflate the congestion window
  552.              * until the acks finally get "unstuck".
  553.              */
  554.             tcb->cwind += tcb->mss;
  555.         }
  556.         return;
  557.     }
  558.     if(tcb->dupacks >= TCPDUPACKS && tcb->cwind > tcb->ssthresh){
  559.         /* The acks have finally gotten "unstuck". So now we
  560.          * can "deflate" the congestion window, i.e. take it
  561.          * back down to where it would be after slow start
  562.          * finishes.
  563.          */
  564.         tcb->cwind = tcb->ssthresh;
  565.     }
  566.     tcb->dupacks = 0;
  567.  
  568.     /* We're here, so the ACK must have actually acked something */
  569.     acked = seg->ack - tcb->snd.una;
  570.  
  571.     /* Expand congestion window if not already at limit and if
  572.      * this packet wasn't retransmitted
  573.      */
  574.     if(tcb->cwind < tcb->snd.wnd && !tcb->flags.retran){
  575.         if(tcb->cwind < tcb->ssthresh){
  576.             /* Still doing slow start/CUTE, expand by amount acked */
  577.             expand = min(acked,tcb->mss);
  578.         } else {
  579.             /* Steady-state test of extra path capacity */
  580.             expand = (tcb->mss * tcb->mss) / tcb->cwind;
  581.         }
  582.         /* Guard against arithmetic overflow */
  583.         if(tcb->cwind + expand < tcb->cwind)
  584.             expand = MAXINT16 - tcb->cwind;
  585.  
  586.         /* Don't expand beyond the offered window */
  587.         if(tcb->cwind + expand > tcb->snd.wnd)
  588.             expand = tcb->snd.wnd - tcb->cwind;
  589.  
  590.         if(expand != 0){
  591. #ifdef    XXX
  592.             /* Kick up the mean deviation estimate to prevent
  593.              * unnecessary retransmission should we already be
  594.              * bandwidth limited
  595.              */
  596.             tcb->mdev += ((long)tcb->srtt * expand) / tcb->cwind;
  597. #endif
  598.             tcb->cwind += expand;
  599.         }
  600.     }
  601.     /* Round trip time estimation */
  602.     if(tcb->flags.rtt_run && seq_ge(seg->ack,tcb->rttseq)){
  603.         /* A timed sequence number has been acked */
  604.         tcb->flags.rtt_run = 0;
  605.         if(!(tcb->flags.retran)){
  606.             /* This packet was sent only once and now
  607.              * it's been acked, so process the round trip time
  608.              */
  609.             int32 rtt = msclock() - tcb->rtt_time;
  610.             int32 abserr = (rtt > tcb->srtt) ? rtt - tcb->srtt : tcb->srtt - rtt;
  611.  
  612.             /* Run SRTT and MDEV integrators, with rounding */
  613.             tcb->srtt = ((AGAIN-1)*tcb->srtt + rtt + (AGAIN/2)) >> LAGAIN;
  614.             tcb->mdev = ((DGAIN-1)*tcb->mdev + abserr + (DGAIN/2)) >> LDGAIN;
  615.  
  616.             rtt_add(tcb->conn.remote.address,rtt);
  617.             /* Reset the backoff level */
  618.             tcb->backoff = 0;
  619.         }
  620.     }
  621.     tcb->sndcnt -= acked;    /* Update virtual byte count on snd queue */
  622.     tcb->snd.una = seg->ack;
  623.  
  624.     /* If we're waiting for an ack of our SYN, note it and adjust count */
  625.     if(!(tcb->flags.synack)){
  626.         tcb->flags.synack = 1;
  627.         acked--;    /* One less byte to pull from real snd queue */
  628.     }
  629.     /* Remove acknowledged bytes from the send queue and update the
  630.      * unacknowledged pointer. If a FIN is being acked,
  631.      * pullup won't be able to remove it from the queue, but that
  632.      * causes no harm.
  633.      */
  634.     pullup(&tcb->sndq,NULLCHAR,acked);
  635.  
  636.     /* Stop retransmission timer, but restart it if there is still
  637.      * unacknowledged data. If there is no more unacked data,
  638.      * the transmitter has gone at least momentarily idle, so
  639.      * record the time for the VJ restart-slowstart rule.
  640.      */
  641.     stop_timer(&tcb->timer);
  642.     if(tcb->snd.una != tcb->snd.nxt)
  643.         start_timer(&tcb->timer);
  644.     else
  645.         tcb->lastactive = msclock();
  646.  
  647.     /* If retransmissions have been occurring, make sure the
  648.      * send pointer doesn't repeat ancient history
  649.      */
  650.     if(seq_lt(tcb->snd.ptr,tcb->snd.una))
  651.         tcb->snd.ptr = tcb->snd.una;
  652.  
  653.     /* Clear the retransmission flag since the oldest
  654.      * unacknowledged segment (the only one that is ever retransmitted)
  655.      * has now been acked.
  656.      */
  657.     tcb->flags.retran = 0;
  658.  
  659.     /* If outgoing data was acked, notify the user so he can send more
  660.      * unless we've already sent a FIN.
  661.      */
  662.     if(acked != 0 && tcb->t_upcall
  663.      && (tcb->state == TCP_ESTABLISHED || tcb->state == TCP_CLOSE_WAIT)){
  664.         (*tcb->t_upcall)(tcb,tcb->window - tcb->sndcnt);
  665.     }
  666. }
  667.  
  668. /* Determine if the given sequence number is in our receiver window.
  669.  * NB: must not be used when window is closed!
  670.  */
  671. static int near
  672. in_window(struct tcb *tcb,int32 seq)
  673. {
  674.     return seq_within(seq,tcb->rcv.nxt,tcb->rcv.nxt + tcb->rcv.wnd - 1);
  675. }
  676.  
  677. /* Process an incoming SYN */
  678. static void near
  679. proc_syn(struct tcb *tcb,char tos,struct tcp *seg)
  680. {
  681.     int16 mtu;
  682.     struct tcp_rtt *tp;
  683.  
  684.     tcb->flags.force = 1;    /* Always send a response */
  685.  
  686.     /* Note: It's not specified in RFC 793, but SND.WL1 and
  687.      * SND.WND are initialized here since it's possible for the
  688.      * window update routine in update() to fail depending on the
  689.      * IRS if they are left unitialized.
  690.      */
  691.     /* Check incoming precedence and increase if higher */
  692.     if(PREC(tos) > PREC(tcb->tos))
  693.         tcb->tos = tos;
  694.  
  695.     tcb->rcv.nxt = seg->seq + 1;    /* p 68 */
  696.     tcb->snd.wl1 = tcb->irs = seg->seq;
  697.     tcb->snd.wnd = seg->wnd;
  698.  
  699.     if(seg->mss != 0)
  700.         tcb->mss = seg->mss;
  701.  
  702.     /* Check the MTU of the interface we'll use to reach this guy
  703.      * and lower the MSS so that unnecessary fragmentation won't occur
  704.      */
  705.     if((mtu = ip_mtu(tcb->conn.remote.address)) != 0) {
  706.         /* Allow space for the TCP and IP headers */
  707.         mtu -= TCPLEN + IPLEN;
  708.         tcb->cwind = tcb->mss = (int16)min(mtu,tcb->mss);
  709.     }
  710.     /* See if there's round-trip time experience */
  711.     if((tp = rtt_get(tcb->conn.remote.address)) != NULLRTT){
  712.         tcb->srtt = tp->srtt;
  713.         tcb->mdev = tp->mdev;
  714.     }
  715. }
  716.  
  717. /* Generate an initial sequence number and put a SYN on the send queue */
  718. void
  719. send_syn(struct tcb *tcb)
  720. {
  721.     tcb->iss = geniss();
  722.     tcb->rttseq = tcb->snd.wl2 = tcb->snd.una = tcb->iss;
  723.     tcb->snd.ptr = tcb->snd.nxt = tcb->rttseq;
  724.     tcb->sndcnt++;
  725.     tcb->flags.force = 1;
  726. }
  727.  
  728. /* Add an entry to the resequencing queue in the proper place */
  729. static void near
  730. add_reseq(struct tcb *tcb,char tos,struct tcp *seg,struct mbuf *bp,int16 length)
  731. {
  732.     /* Allocate reassembly descriptor */
  733.     struct reseq *rp = mxallocw(sizeof(struct reseq));
  734.  
  735.     /* Place on reassembly list sorting by starting seq number */
  736.     struct reseq *rp1 = tcb->reseq;
  737.  
  738.     ASSIGN(rp->seg,*seg);
  739.     rp->tos = tos;
  740.     rp->bp = bp;
  741.     rp->length = length;
  742.  
  743.     if(rp1 == NULLRESEQ || seq_lt(seg->seq,rp1->seg.seq)){
  744.         /* Either the list is empty, or we're less than all other
  745.          * entries; insert at beginning.
  746.          */
  747.         rp->next = rp1;
  748.         tcb->reseq = rp;
  749.     } else {
  750.         /* Find the last entry less than us */
  751.         for(;;) {
  752.             if(rp1->next == NULLRESEQ || seq_lt(seg->seq,rp1->next->seg.seq)) {
  753.                 /* We belong just after this one */
  754.                 rp->next = rp1->next;
  755.                 rp1->next = rp;
  756.                 break;
  757.             }
  758.             rp1 = rp1->next;
  759.         }
  760.     }
  761. }
  762.  
  763. /* Fetch the first entry off the resequencing queue */
  764. static void near
  765. get_reseq(struct tcb *tcb,char *tos,struct tcp *seg,struct mbuf **bp,int16 *length)
  766. {
  767.     struct reseq *rp;
  768.  
  769.     if((rp = tcb->reseq) != NULLRESEQ) {
  770.         tcb->reseq = rp->next;
  771.  
  772.         *tos = rp->tos;
  773.         ASSIGN(*seg,rp->seg);
  774.         *bp = rp->bp;
  775.         *length = rp->length;
  776.         xfree(rp);
  777.     }
  778. }
  779.  
  780. /* Trim segment to fit window. Return 0 if OK, -1 if segment is
  781.  * unacceptable.
  782.  */
  783. static int near
  784. trim(struct tcb *tcb,struct tcp *seg,struct mbuf **bpp,int16 *length)
  785. {
  786.     long dupcnt, excess;
  787.     int16 len = *length;        /* Segment length including flags */
  788.     char accept = 0;
  789.  
  790.     if(seg->flags.syn)
  791.         len++;
  792.     if(seg->flags.fin)
  793.         len++;
  794.  
  795.     /* Acceptability tests */
  796.     if(tcb->rcv.wnd == 0){
  797.         /* Only in-order, zero-length segments are acceptable when
  798.          * our window is closed.
  799.          */
  800.         if(seg->seq == tcb->rcv.nxt && len == 0){
  801.             return 0;    /* Acceptable, no trimming needed */
  802.         }
  803.     } else {
  804.         /* Some part of the segment must be in the window */
  805.         if(in_window(tcb,seg->seq)){
  806.             accept++;    /* Beginning is */
  807.         } else if(len != 0){
  808.             if(in_window(tcb,(int32)(seg->seq+len-1)) || /* End is */
  809.              seq_within(tcb->rcv.nxt,seg->seq,(int32)(seg->seq+len-1))){ /* Straddles */
  810.                 accept++;
  811.             }
  812.         }
  813.     }
  814.     if(!accept){
  815.         tcb->rerecv += len;    /* Assume all of it was a duplicate */
  816.         free_p(*bpp);
  817.         return -1;
  818.     }
  819.     if((dupcnt = tcb->rcv.nxt - seg->seq) > 0){
  820.         tcb->rerecv += dupcnt;
  821.         /* Trim off SYN if present */
  822.         if(seg->flags.syn){
  823.             /* SYN is before first data byte */
  824.             seg->flags.syn = 0;
  825.             seg->seq++;
  826.             dupcnt--;
  827.         }
  828.         if(dupcnt > 0){
  829.             pullup(bpp,NULLCHAR,(int16)dupcnt);
  830.             seg->seq += dupcnt;
  831.             *length -= dupcnt;
  832.         }
  833.     }
  834.     if((excess = seg->seq + *length - (tcb->rcv.nxt + tcb->rcv.wnd)) > 0){
  835.         tcb->rerecv += excess;
  836.         /* Trim right edge */
  837.         *length -= excess;
  838.         trim_mbuf(bpp,*length);
  839.         seg->flags.fin = 0;    /* FIN follows last data byte */
  840.     }
  841.     return 0;
  842. }
  843.